﻿// Decompiled with JetBrains decompiler
// Type: TaleWorlds.MountAndBlade.View.MissionViews.SiegeWeapon.RangedSiegeWeaponView
// Assembly: TaleWorlds.MountAndBlade.View, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: 61152EB8-513B-4D4A-8AC0-0D1465C6CF6C
// Assembly location: D:\steam\steamapps\common\Mount & Blade II Bannerlord\Modules\Native\bin\Win64_Shipping_Client\TaleWorlds.MountAndBlade.View.dll

using TaleWorlds.DotNet;
using TaleWorlds.Engine;
using TaleWorlds.InputSystem;
using TaleWorlds.Library;
using TaleWorlds.MountAndBlade.View.Screens;

#nullable disable
namespace TaleWorlds.MountAndBlade.View.MissionViews.SiegeWeapon
{
  public class RangedSiegeWeaponView : UsableMissionObjectComponent
  {
    private float _cameraYaw;
    private float _cameraPitch;
    private float _cameraRoll;
    private float _cameraInitialYaw;
    private float _cameraInitialPitch;
    private Vec3 _cameraPositionOffset;
    private bool _isInWeaponCameraMode;
    protected bool UsesMouseForAiming;

    public RangedSiegeWeapon RangedSiegeWeapon { get; private set; }

    public MissionScreen MissionScreen { get; private set; }

    public Camera Camera { get; private set; }

    public GameEntity CameraHolder => this.RangedSiegeWeapon.cameraHolder;

    public Agent PilotAgent => this.RangedSiegeWeapon.PilotAgent;

    internal void Initialize(RangedSiegeWeapon rangedSiegeWeapon, MissionScreen missionScreen)
    {
      this.RangedSiegeWeapon = rangedSiegeWeapon;
      this.MissionScreen = missionScreen;
    }

    protected override void OnAdded(Scene scene)
    {
      base.OnAdded(scene);
      if (!((NativeObject) this.CameraHolder != (NativeObject) null))
        return;
      this.CreateCamera();
    }

    protected override void OnMissionReset()
    {
      base.OnMissionReset();
      if (!((NativeObject) this.CameraHolder != (NativeObject) null))
        return;
      this._cameraYaw = this._cameraInitialYaw;
      this._cameraPitch = this._cameraInitialPitch;
      this.ApplyCameraRotation();
      this._isInWeaponCameraMode = false;
      this.ResetCamera();
    }

    public override bool IsOnTickRequired() => true;

    protected override void OnTick(float dt)
    {
      base.OnTick(dt);
      if (GameNetwork.IsReplay)
        return;
      this.HandleUserInput(dt);
    }

    protected virtual void HandleUserInput(float dt)
    {
      if (this.PilotAgent != null && this.PilotAgent.IsMainAgent && (NativeObject) this.CameraHolder != (NativeObject) null)
      {
        if (!this._isInWeaponCameraMode)
        {
          this._isInWeaponCameraMode = true;
          this.StartUsingWeaponCamera();
        }
        this.HandleUserCameraRotation(dt);
      }
      if (this._isInWeaponCameraMode && (this.PilotAgent == null || !this.PilotAgent.IsMainAgent))
      {
        this._isInWeaponCameraMode = false;
        this.ResetCamera();
      }
      this.HandleUserAiming(dt);
    }

    private void CreateCamera()
    {
      this.Camera = Camera.CreateCamera();
      this.Camera.SetFovVertical(1.04719758f, Screen.AspectRatio, 0.1f, 1000f);
      this.Camera.Entity = this.CameraHolder;
      MatrixFrame frame = this.CameraHolder.GetFrame();
      Vec3 eulerAngles = frame.rotation.GetEulerAngles();
      this._cameraYaw = eulerAngles.z;
      this._cameraPitch = eulerAngles.x;
      this._cameraRoll = eulerAngles.y;
      this._cameraPositionOffset = frame.origin;
      this._cameraPositionOffset.RotateAboutZ(-this._cameraYaw);
      this._cameraPositionOffset.RotateAboutX(-this._cameraPitch);
      this._cameraPositionOffset.RotateAboutY(-this._cameraRoll);
      this._cameraInitialYaw = this._cameraYaw;
      this._cameraInitialPitch = this._cameraPitch;
    }

    protected virtual void StartUsingWeaponCamera()
    {
      if ((NativeObject) this.CameraHolder != (NativeObject) null && (NativeObject) this.Camera.Entity != (NativeObject) null)
      {
        this.MissionScreen.CustomCamera = this.Camera;
        Agent.Main.IsLookDirectionLocked = true;
      }
      else
        Debug.FailedAssert("Camera entities are null.", "C:\\Develop\\MB3\\Source\\Bannerlord\\TaleWorlds.MountAndBlade.View\\MissionViews\\SiegeWeapon\\RangedSiegeWeaponView.cs", nameof (StartUsingWeaponCamera), 140);
    }

    private void ResetCamera()
    {
      if (!((NativeObject) this.MissionScreen.CustomCamera == (NativeObject) this.Camera))
        return;
      this.MissionScreen.CustomCamera = (Camera) null;
      if (Agent.Main == null)
        return;
      Agent.Main.IsLookDirectionLocked = false;
      this.MissionScreen.SetExtraCameraParameters(false, 0.0f);
    }

    protected virtual void HandleUserCameraRotation(float dt)
    {
      float cameraYaw = this._cameraYaw;
      double cameraPitch1 = (double) this._cameraPitch;
      if (this.MissionScreen.SceneLayer.Input.IsGameKeyDown(10))
      {
        this._cameraYaw = this._cameraInitialYaw;
        this._cameraPitch = this._cameraInitialPitch;
      }
      this._cameraYaw += (float) ((double) this.MissionScreen.SceneLayer.Input.GetMouseMoveX() * (double) dt * 0.20000000298023224);
      this._cameraPitch += (float) ((double) this.MissionScreen.SceneLayer.Input.GetMouseMoveY() * (double) dt * 0.20000000298023224);
      this._cameraYaw = MBMath.ClampFloat(this._cameraYaw, 1.57079637f, 4.712389f);
      this._cameraPitch = MBMath.ClampFloat(this._cameraPitch, 1.04719758f, 1.74532938f);
      double cameraPitch2 = (double) this._cameraPitch;
      if (cameraPitch1 == cameraPitch2 && (double) cameraYaw == (double) this._cameraYaw)
        return;
      this.ApplyCameraRotation();
    }

    private void ApplyCameraRotation()
    {
      MatrixFrame identity = MatrixFrame.Identity;
      identity.rotation.RotateAboutUp(this._cameraYaw);
      identity.rotation.RotateAboutSide(this._cameraPitch);
      identity.rotation.RotateAboutForward(this._cameraRoll);
      identity.Strafe(this._cameraPositionOffset.x);
      identity.Advance(this._cameraPositionOffset.y);
      identity.Elevate(this._cameraPositionOffset.z);
      this.CameraHolder.SetFrame(ref identity);
    }

    private void HandleUserAiming(float dt)
    {
      bool flag = false;
      float inputX = 0.0f;
      float inputY = 0.0f;
      if (this.PilotAgent != null && this.PilotAgent.IsMainAgent)
      {
        if (this.UsesMouseForAiming)
        {
          InputContext input = this.MissionScreen.SceneLayer.Input;
          float num1 = dt / 0.0006f;
          float num2 = input.GetMouseMoveX() + num1 * input.GetGameKeyAxis("CameraAxisX");
          float num3 = input.GetMouseMoveY() + -num1 * input.GetGameKeyAxis("CameraAxisY");
          if (NativeConfig.InvertMouse)
            num3 *= -1f;
          Vec2 vec2_1 = new Vec2(-num2, -num3);
          if (vec2_1.IsNonZero())
          {
            float num4 = MathF.Min(5f, MathF.Pow(vec2_1.Normalize(), 1.5f) * 0.025f);
            Vec2 vec2_2 = vec2_1 * num4;
            inputX = vec2_2.x;
            inputY = vec2_2.y;
          }
        }
        else
        {
          if (this.MissionScreen.SceneLayer.Input.IsGameKeyDown(2))
            inputX = 1f;
          else if (this.MissionScreen.SceneLayer.Input.IsGameKeyDown(3))
            inputX = -1f;
          if (this.MissionScreen.SceneLayer.Input.IsGameKeyDown(0))
            inputY = 1f;
          else if (this.MissionScreen.SceneLayer.Input.IsGameKeyDown(1))
            inputY = -1f;
        }
        if ((double) inputX != 0.0)
          flag = true;
        if ((double) inputY != 0.0)
          flag = true;
      }
      if (!flag)
        return;
      this.RangedSiegeWeapon.GiveInput(inputX, inputY);
    }
  }
}
